home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Carousel Volume 2 #1
/
carousel.iso
/
mactosh
/
patches
/
thinkc.sit
/
Think ƒ
/
Math881.c
< prev
next >
Wrap
Text File
|
1989-01-16
|
6KB
|
406 lines
/*
Math library for LightspeedC
(C) Copyright 1986 THINK Technologies. All rights reserved.
For details, refer to Harbison & Steele's "C: A Reference Manual",
Chapter 11.
Two versions of each function are defined by this library: an
error-checking version (e.g. "sin") and a non-error-checking
version (e.g. "_sin").
The non-underscore names can be made to refer to the non-error-
checking functions by #defining _NOERRORCHECK_ before #including
"math.h". Doing so in THIS file suppresses the definitions of
the error-checking versions of the functions altogether.
*/
/*#define _NOERRORCHECK_*/
#include "Math.h"
/* useful constants */
static double Zero = 0.0;
static double One = 1.0;
static double MinusOne = -1.0;
static double Pi = PI;
static double Pi2 = PI2;
/* seed for pseudo-random number generator */
static unsigned long seed = 1;
#ifdef _ERRORCHECK_
extern int errno; /* defined in stdio */
#define EDOM 33
#define ERANGE 34
#define ERROR 0x0000FF00 /* 68881 mask to check for exceptions */
/* GetState() and ClearExceptions() are in Math881.a */
/*
GetState returns the entire 68881 Floating-Point Status Register (FPSR);
ClearExceptions ANDs the FPSR with $00FF0000 to clear all but the quotient
byte.
*/
long GetState();
void ClearExceptions();
#define DomainCheck(test, result) if (test) { \
errno = EDOM; \
return(result); \
}
#define RangeCheck(target) if (GetState() & ERROR) { \
errno = ERANGE; \
target = Max; \
}
static short _Max[] = { 0x7FFE, 0x0000, 0x7FFF, 0xFFFF, 0xFFFF, 0xFFFF };
static short _MinusMax[] = { 0xFFFE, 0x0000, 0x7FFF, 0xFFFF, 0xFFFF, 0xFFFF };
#define Max (* (double *) _Max)
#define MinusMax (* (double *) _MinusMax)
#else
#define DomainCheck(test, result)
#define RangeCheck(value)
#endif
/*
the functions rand, srand, and xfersign
get defined regardless of whether there's error checking or not.
*/
/* rand - pseudo-random number generator (ANSI C standard) */
int rand()
{
seed = seed * 1103515245 + 12345;
asm {
move.w seed,d0 ; high word of long
andi.w #0x7FFF,d0 ; remove high bit
}
}
/* srand - seed pseudo-random number generator */
void srand(n)
unsigned n;
{
seed = n;
}
/* xfersign - transfer sign from one floating number to another */
static
xfersign(x, yp)
double x, *yp;
{
asm {
movea.l yp,a0
bclr #7,(a0)
tst.w x
bpl.s @1
bset #7,(a0)
@1 }
}
#ifdef _ERRORCHECK_
/* ---------- math functions (alphabetically) ---------- */
/*
* acos - inverse circular cosine
*
*/
double acos(x)
register double x;
{
DomainCheck(x > One || x < MinusOne, Zero);
if (x == MinusOne)
return(Pi);
return(_acos(x));
}
/*
* asin - inverse circular sine
*
*/
double asin(x)
register double x;
{
double y = fabs(x);
DomainCheck(y > One, Zero);
return(_asin(x));
}
/*
* atan - inverse circular tangent - defined as macro in Math881.h
*
*/
double atan(x)
register double x;
{
return(_atan(x));
}
double atan2(y, x)
register double y, x;
{
return(_atan2(y, x));
}
/*
* ceil - round up to an integer
*
*/
double ceil(x)
register double x;
{
return(_ceil(x));
}
/*
* cos - circular cosine
*
*/
double cos(x)
register double x;
{
return(_cos(x));
}
/*
* cosh - hyperbolic cosine
*
*/
double cosh(x)
register double x;
{
ClearExceptions();
x = _cosh(x);
RangeCheck(x);
return(x);
}
/*
* exp - exponential function
*
*/
double exp(x)
register double x;
{
ClearExceptions();
x = _exp(x);
RangeCheck(x);
return(x);
}
/*
* fabs - absolute value of a floating number
*
*/
double fabs(x)
register double x;
{
return(_fabs(x));
}
/*
* floor - round down to an integer
*
*/
double floor(x)
register double x;
{
return(_floor(x));
}
/*
* fmod - remainder function
*
* This computes a value z, with the same sign as x, such that for some
* integer k, k*y + z == x.
*
*/
double fmod(x, y)
register double x, y;
{
return(_fmod(x, y));
}
/*
* frexp - split floating number into fraction/exponent
*
* This computes a value z, where 0.5 <= fabs(z) < 1.0, and an integer n such
* that z*(2^n) == x.
*
*/
double frexp(x, nptr)
register double x;
register int *nptr;
{
return(_frexp(x, nptr));
}
/*
* ldexp - combine fraction/exponent into a floating number
*
*/
double ldexp(x, n)
register double x;
register int n;
{
return(_ldexp(x, n));
}
/*
* log - natural logarithm
*
*/
double log(x)
register double x;
{
DomainCheck(x <= 0, MinusMax);
return(_log(x));
}
/*
* log10 - logarithm base 10
*
*/
double log10(x)
register double x;
{
DomainCheck(x <= 0, MinusMax);
return(_log10(x));
}
/*
* modf - split a floating number into fraction/integer
*
*/
double modf(x, nptr)
double x, *nptr;
{
return(_modf(x, nptr));
}
/* pow - power function (exponentiation) */
double pow(x, y)
register double x, y;
{
return(_pow(x, y)); /* _pow() does the proper error checking. */
}
/*
* sin - circular sine
*
*/
double sin(x)
register double x;
{
return(_sin(x));
}
/*
* sinh - hyperbolic sine
*
*/
double sinh(x)
register double x;
{
register double y;
ClearExceptions();
y = _sinh(x);
RangeCheck(y);
return(y);
}
/*
* sqrt - square root
*
*/
double sqrt(x)
register double x;
{
DomainCheck(x < 0, Zero);
return(_sqrt(x));
}
/*
* tan - circular tangent
*
*/
double tan(x)
register double x;
{
ClearExceptions();
x = _tan(x);
RangeCheck(x);
return(x);
}
/*
* tanh - hyperbolic tangent
*
*/
double tanh(x)
double x;
{
return(_tanh(x));
}
#endif _ERRORCHECK_